/*
 ** Licensed under the Apache License, Version 2.0 (the "License");
 ** you may not use this file except in compliance with the License.
 ** You may obtain a copy of the License at
 **
 **     http://www.apache.org/licenses/LICENSE-2.0
 **
 ** Unless required by applicable law or agreed to in writing, software
 ** distributed under the License is distributed on an "AS IS" BASIS,
 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */

package com.duoqin.guard;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

import com.duoqin.IDuoqinGuardService;
import com.duoqin.IDuoqinGuardCallback;
import com.duoqin.chat.IDuoqinChatCallback;

/**
 * System private event record manager.
 * {@hide}
 */
public class GuardServiceManager {
    private static final String TAG = "Duoqin.GuardS";
    private static final Object mServiceLock = new Object();
    private static IDuoqinGuardService mService = null;
    private static IDuoqinChatCallback mChatCallback = null;
    private static IDuoqinGuardCallback mGuardCallback = null;
    private static GuardServiceManager mInstance;

    private static final ComponentName DEFAULT_COMPONENT = new ComponentName(
            "com.duoqin.remoteservice", "com.duoqin.remoteservice.LocalService");
    private static final RecordConnection mRecordConn = new RecordConnection();

    static class RecordConnection implements ServiceConnection {
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d(TAG, "onServiceConnected");

            if (service == null) {
                Log.i(TAG, "service == null");
                return;
            }

            if (mService != null) {
                synchronized (mServiceLock) {
                    mService = IDuoqinGuardService.Stub.asInterface(service);
                }
            }
            else {
                mService = IDuoqinGuardService.Stub.asInterface(service);
            }
            registerChatCallback(mChatCallback);
            registerGuardCallback(mGuardCallback);
        }

        public void onServiceDisconnected(ComponentName name) {
            Log.d(TAG, "onServiceDisconnected");
            if (mService != null) {
                synchronized (mServiceLock) {
                    mService = null;
                }
            }
        }
    }

    public static GuardServiceManager getInstance(Context context, IDuoqinChatCallback chatCallback,
                                                  IDuoqinGuardCallback guardCallback) {
        if (mInstance == null) {
            mInstance = new GuardServiceManager(context.getApplicationContext());
        }
        mChatCallback = chatCallback;
        mGuardCallback = guardCallback;
        return mInstance;
    }

    private GuardServiceManager(Context context) {
        if (mService == null) {
            connectToService(context);
        }
    }


    private boolean connectToService(Context context) {
        Log.i(TAG, "Trying to bind to Service");

        try {
            Intent service = new Intent().setComponent(DEFAULT_COMPONENT);
            if (context.bindService(service, mRecordConn, Context.BIND_AUTO_CREATE)) {
                return true;
            }
        } catch (Exception e) {
            Log.e(TAG, "failed to bind to Service");
        }
        return false;
    }

    public void sendChatMessage(String chatId) {
        if (mService != null) {
            synchronized (mServiceLock) {
                try {
                    mService.sendChatMessage(chatId);
                } catch (RemoteException e) {
                    Log.e(TAG, "event RemoteException");
                }
            }
        }
    }

    public void requestInstall(String packageName, String appLabel, String fileUriString) {
        if (mService != null) {
            synchronized (mServiceLock) {
                try {
                    mService.requestInstall(packageName, appLabel, fileUriString);
                } catch (RemoteException e) {
                    Log.e(TAG, "event RemoteException");
                }
            }
        }
    }

    public static void registerChatCallback(IDuoqinChatCallback cb) {
        if (mService != null) {
            try {
                mService.registerChatCallback(cb);
            } catch (RemoteException e) {
                Log.e(TAG, "event RemoteException");
            }
        }
    }

    public static void registerGuardCallback(IDuoqinGuardCallback cb) {
        if (mService != null) {
            try {
                mService.registerGuardCallback(cb);
            } catch (RemoteException e) {
                Log.e(TAG, "event RemoteException");
            }
        }
    }
}
